﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WowVoiceBox
{
    /// <summary>
    /// Interaction logic for Options.xaml
    /// </summary>
    public partial class OptionsWindow : Window
    {
        private List<SpeechCommand> cmdList;
        public List<SpeechCommand> CommandList
        {
            get { return cmdList; }
            set { cmdList = value; }
        }

        private SpeechCommand curCommand;

        public OptionsWindow(List<SpeechCommand> cmds)
        {
            InitializeComponent();

            cmdList = new List<SpeechCommand>(cmds);

            lbCommandList.ItemsSource = cmdList;

            lbWindowNames.ItemsSource = WowVoiceBox.Properties.Settings.Default.WowWindowNames;
            //lbWindowNames.Items
        }

        private void lbCommandList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            curCommand = (SpeechCommand)lbCommandList.SelectedItem;

            UpdateFromCurCommand();
        }

        private void UpdateFromCurCommand()
        {
            if (curCommand == null)
                return;

            if (curCommand.CommandType == SpeechCommandType.SingleKey)
            {
                rbSingleKey.IsChecked = true;
                tbSingleKeyCommand.Text = "";
                foreach (int modifier in curCommand.KeyModifiers)
                {
                    switch (modifier)
                    {
                        case SpeechCommand.VK_ALT:
                            tbSingleKeyCommand.Text += "ALT + ";
                            break;
                        case SpeechCommand.VK_SHIFT:
                            tbSingleKeyCommand.Text += "SHIFT + ";
                            break;
                        case SpeechCommand.VK_CONTROL:
                            tbSingleKeyCommand.Text += "CTRL + ";
                            break;
                    }
                }
                tbSingleKeyCommand.Text += KeyInterop.KeyFromVirtualKey(curCommand.CommandKey).ToString();
                gridMacroCommand.Visibility = Visibility.Hidden;
                gridSingleKeyCommand.Visibility = Visibility.Visible;
            }
            else
            {
                rbMacro.IsChecked = true;
                tbMacroCommand.Text = curCommand.CommandString;
                gridMacroCommand.Visibility = Visibility.Visible;
                gridSingleKeyCommand.Visibility = Visibility.Hidden;
            }

            tbVoiceCommand.Text = curCommand.VoiceCommand;

            cbBroadcast.IsChecked = curCommand.Broadcast;
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
            this.Close();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            this.Close();
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (curCommand != null)
            {
                cmdList.Remove(curCommand);
                RefreshList();
            }
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            curCommand = new SpeechCommand();

            cmdList.Add(curCommand);

            RefreshList();

            lbCommandList.SelectedIndex = lbCommandList.Items.Count - 1;
            lbCommandList.ScrollIntoView(curCommand);

            UpdateFromCurCommand();
        }

        private void RefreshList()
        {
            int selectedIndex = lbCommandList.SelectedIndex;
            lbCommandList.ItemsSource = null;
            lbCommandList.ItemsSource = cmdList;

            // Make sure we try to select a valid one
            if (selectedIndex >= lbCommandList.Items.Count)
                selectedIndex = lbCommandList.Items.Count - 1;

            lbCommandList.SelectedIndex = selectedIndex;
        }

        private void tbSingleKeyCommand_KeyDown(object sender, KeyEventArgs e)
        {
            if (curCommand == null)
                return;

            String keyString = "";

            // We want to ignore the CTRL ALT and SHIFT keys if they're what raised the event
            switch (e.Key)
            {
                case Key.LeftShift:
                case Key.LeftAlt:
                case Key.LeftCtrl:
                case Key.RightAlt:
                case Key.RightCtrl:
                case Key.RightShift:
                    return;
            }

            curCommand.KeyModifiers.Clear();

            if ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
                keyString += "CRTL + ";
                curCommand.KeyModifiers.Add(SpeechCommand.VK_CONTROL);
            }

            if ((e.KeyboardDevice.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
            {
                keyString += "ALT + ";
                curCommand.KeyModifiers.Add(SpeechCommand.VK_ALT);
            }

            if ((e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
            {
                keyString += "SHIFT + ";
                curCommand.KeyModifiers.Add(SpeechCommand.VK_SHIFT);
            }

            curCommand.CommandKey = KeyInterop.VirtualKeyFromKey(e.Key);

            keyString += e.Key.ToString();

            tbSingleKeyCommand.Text = keyString;
        }

        private void rbMacro_Checked(object sender, RoutedEventArgs e)
        {
            if (curCommand == null)
                return;

            curCommand.CommandType = SpeechCommandType.Macro;
            tbMacroCommand.Text = curCommand.CommandString;
            gridMacroCommand.Visibility = Visibility.Visible;
            gridSingleKeyCommand.Visibility = Visibility.Hidden;
        }

        private void rbSingleKey_Checked(object sender, RoutedEventArgs e)
        {
            if (curCommand == null)
                return;

            curCommand.CommandType = SpeechCommandType.SingleKey;
            tbSingleKeyCommand.Text = "";
            foreach (int modifier in curCommand.KeyModifiers)
            {
                switch (modifier)
                {
                    case SpeechCommand.VK_ALT:
                        tbSingleKeyCommand.Text += "ALT + ";
                        break;
                    case SpeechCommand.VK_SHIFT:
                        tbSingleKeyCommand.Text += "SHIFT + ";
                        break;
                    case SpeechCommand.VK_CONTROL:
                        tbSingleKeyCommand.Text += "CTRL + ";
                        break;
                }
            }
            tbSingleKeyCommand.Text += KeyInterop.KeyFromVirtualKey(curCommand.CommandKey).ToString();
            gridMacroCommand.Visibility = Visibility.Hidden;
            gridSingleKeyCommand.Visibility = Visibility.Visible;
        }

        private void tbVoiceCommand_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (curCommand == null)
                return;

            curCommand.VoiceCommand = tbVoiceCommand.Text;
            RefreshList();
        }

        private void cbBroadcast_Checked(object sender, RoutedEventArgs e)
        {
            if (curCommand == null)
                return;

            curCommand.Broadcast = cbBroadcast.IsChecked.Value;
        }

        private void tbMacroCommand_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (curCommand == null)
                return;

            curCommand.CommandString = tbMacroCommand.Text;
        }

        private void btnAddWindowName_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            InputPrompt prompt = new InputPrompt("Enter Window Title", "Enter the window title to add:");
            prompt.ShowDialog();
            if (prompt.Result == MessageBoxResult.OK)
            {
                WowVoiceBox.Properties.Settings.Default.WowWindowNames.Add(prompt.Value);
                WowVoiceBox.Properties.Settings.Default.Save();
                lbWindowNames.ItemsSource = null;
                lbWindowNames.ItemsSource = WowVoiceBox.Properties.Settings.Default.WowWindowNames;
            }
        }

        private void btnDeleteWindowName_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (lbWindowNames.SelectedItem == null)
                return;

            String selectedWindow = lbWindowNames.SelectedItem.ToString();
            if (MessageBox.Show("Are you sure you want to delete window title '" + selectedWindow + "'?", "Confirm Deletion", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK)
            {
                WowVoiceBox.Properties.Settings.Default.WowWindowNames.Remove(selectedWindow);
                WowVoiceBox.Properties.Settings.Default.Save();
                lbWindowNames.ItemsSource = null;
                lbWindowNames.ItemsSource = WowVoiceBox.Properties.Settings.Default.WowWindowNames;
            }
        }

    }
}
